package de.kalinasch.pa.placereminder.service;

import java.util.ArrayList;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import de.kalinasch.pa.placereminder.ActiveReminderActivity;
import de.kalinasch.pa.placereminder.R;
import de.kalinasch.pa.placereminder.ShowReminderDetailActivity;
import de.kalinasch.pa.placereminder.database.IncidentDataSource;
import de.kalinasch.pa.placereminder.dmo.PositionDMO;

/**
 * The service runs in the background and runs the listener that compares the current position with the saved reminder
 * positions.
 * 
 * @author dkalinasch
 */
public class GPSService extends Service {
	private IncidentDataSource dbadapter;
	private ArrayList<PositionDMO> positionsToCompare;
	private NotificationManager notManager;
	private Notification notification;

	LocationManager locationManager;
	CustomLocationListener locationListener;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		Log.i("SERVICE", "Service.onCreate() is called");
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		dbadapter = new IncidentDataSource(this);
		notManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
	}

	@Override
	public void onStart(Intent _intent, int _startId) {
		Log.i("SERVICE", "Service.onStart() is called");
		locationListener = new CustomLocationListener();
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, locationListener);
		positionsToCompare = new ArrayList<PositionDMO>();
		positionsToCompare = dbadapter.getAllPositionDMO();
	}

	@Override
	public void onDestroy() {
		Log.i("SERVICE", "Service.onDestroy() is called");
		locationManager.removeUpdates(locationListener);
		super.onDestroy();
	}

	/**
	 * The inner class listens to the changes of the location an triggers the comparison of current position and the
	 * position of the saved incidents. Only the onLocationChanged() method is needed in the PlaceReminder App.
	 * 
	 * @author dkalinasch
	 */
	class CustomLocationListener implements LocationListener {
		public void onLocationChanged(Location _location) {
			checkDistance(_location);
		}

		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	/**
	 * Compares the longitude and latitude of the current position with positions of every reminder.
	 * 
	 * @param _location
	 */
	private void checkDistance(Location _location) {
		Log.i("Service", "Position changed, check distance of saved places");
		Location tmp = new Location(LocationManager.GPS_PROVIDER);
		float distance = 0f;
		ArrayList<PositionDMO> matchPosition = new ArrayList<PositionDMO>();
		for (PositionDMO position : positionsToCompare) {
			tmp.setLatitude(position.getLatitude());
			tmp.setLongitude(position.getLongitude());

			distance = _location.distanceTo(tmp);
			if (distance < position.getRadius()) {
				createNotification(position);
				// after the user is notified, the position is removed from the current positions that were checked
				matchPosition.add(position);
			}
		}
		positionsToCompare.removeAll(matchPosition);
	}

	/**
	 * this method creates a notification for the user. The user is informed about the event that he is near a location
	 * to which he would like to be reminded.
	 * 
	 * @param _position
	 */
	private void createNotification(PositionDMO _position) {
		String notText = getString(R.string.app_name);
		long when = System.currentTimeMillis();
		notification = new Notification(android.R.drawable.ic_menu_info_details, notText, when);
		String title = _position.getTitle();
		String text = _position.getDescription();

		Intent intent = new Intent(this, ActiveReminderActivity.class);
		intent.putExtra(ShowReminderDetailActivity.INCIDENT_ID, _position.getId());
		PendingIntent startIntent = PendingIntent.getActivity(this, 0, intent, 0);
		notification.setLatestEventInfo(this, title, text, startIntent);
		notManager.notify(1, notification);
	}
}
